<?php

namespace Api\Library;

/**
 * 加密类
 * @author 许诺
 */
class Crypt {

    /**
     * 加密KEY值
     * @var string
     */
    protected $key = '';

    /**
     * 加密IV值
     * @var string
     */
    protected $iv = '';

    /**
     * 密码类型
     * @var string
     */
    protected $cipher = '';

    /**
     * 加密模式
     * @var string
     */
    protected $mode = '';

    /**
     * 块大小
     * @var integer
     */
    protected $block_size = '';

    /**
     * 构造方法
     * @param string $cipher 密码类型
     * @param string $mode 加密模式
     * @param string $key 加密KEY值
     * @param string $iv 加密IV值
     * @param integer $block_size 加密块大小
     */
    public function __construct($cipher, $mode, $key, $iv = '', $block_size = '') {
        $this->cipher = $cipher;
        $this->mode = $mode;
        $this->key = $key;
        //奇葩，已经不需要自动生成IV了，因为IV值竟然可以为空。
        $this->iv = $iv;
        /*
          if (!empty($iv)) {
          $this->iv = $iv;
          } else {
          $size = mcrypt_get_iv_size($cipher, $mode);
          $iv = mcrypt_create_iv($size);
          $this->iv = $iv;
          }
         */
        if (!is_numeric($block_size)) {
            $this->block_size = mcrypt_get_block_size($this->cipher, $this->mode);
        } else {
            $this->block_size = $block_size;
        }
    }

    /**
     * 添加PKCS7填充
     * @param string &$string
     */
    protected function addPKCS7Padding(&$string) {

        $padding = $this->block_size - (strlen($string) % $this->block_size);
        $string .= str_repeat(chr($padding), $padding);
    }

    /**
     * 去除PKCS7填充
     * @param string $string
     */
    protected function stripPKCS7Padding(&$string) {
        $length = strlen($string);
        $end_char = ord($string{$length - 1});
        if ($end_char <= $this->block_size) {
            $string = substr($string, 0, $length - $end_char);
        }
    }

    /**
     * 加密字符串
     * @param string $string
     * @return string
     */
    public function encode($string) {
        $this->addPKCS7Padding($string);
        return base64_encode(@mcrypt_encrypt($this->cipher, $this->key, $string, $this->mode, $this->iv));
    }

    /**
     * 解密字符串
     * @param string $string
     * @return string
     */
    public function decode($string) {
        $string = @mcrypt_decrypt($this->cipher, $this->key, base64_decode(str_replace(' ', '+', $string)), $this->mode, $this->iv);
        $this->stripPKCS7Padding($string);
        return $string;
    }

    /**
     * 获取IV值
     * @return string
     */
    public function getIV() {
        return $this->iv;
    }

}
